package xiao_jin.fantastic_journey.api.capability;

import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;

import java.util.function.Function;

public abstract class Capability {
    protected Identifier id;

    protected Capability(Identifier id) {
        this.id = id;
    }

    public Identifier getID() {
        return this.id;
    }

    public final void writeInto(NbtCompound nbt) {
        NbtCompound nbtCompound = new NbtCompound();
        writeToNBT(nbtCompound);
        nbt.put(this.id.toString(), nbtCompound);
    }

    public final void readIn(NbtCompound nbt) {
        NbtCompound nbtCompound = nbt.contains(this.id.toString()) ? nbt.getCompound(this.id.toString()) : new NbtCompound();
        this.readFromNBT(nbtCompound);
    }

    abstract public void init();

    abstract protected void readFromNBT(NbtCompound nbt);

    abstract protected void writeToNBT(NbtCompound nbt);

    public static <T extends Capability> void run(T cap, PlayerEntity entity, boolean isRemote, Function<T, Void> func) {
        NbtCompound nbt = entity.PC$getOrCreateNBTTagCompound();
        cap.readIn(nbt);
        func.apply(cap);
        cap.writeInto(nbt);
        if (!isRemote) ServerPlayNetworking.send((ServerPlayerEntity) entity, new CapabilityPayload(cap));
        else ClientPlayNetworking.send(new CapabilityPayload(cap));
    }
}
